﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;
using System.Xml;
using System.Collections.Specialized;
using System.IO;
namespace Tracy.CoreLib.Data
{
    public class RssFeedSource : ManagedXmlModel_CommonFunctions, IManagedXmlModelItem
    {
        #region 构造函数
        public RssFeedSource() : base() { }
        public RssFeedSource(string xml) : base(xml) { }
        public RssFeedSource(XmlNode node) : base(node) { }
        #endregion

        public override void SetValue(string key, string value)
        {
            switch(key) 
            {
                case Constants.CONST_TAG_LASTUPDATE: LastUpdate = Convert.ToDateTime(value); break;
                case Constants.CONST_TAG_SCHEMAID: SchemaId = Convert.ToInt32(value); break;
                default: base.SetValue(key, value); break;
            }
        }

        private DateTime lastUpdate;
        public DateTime LastUpdate
        {
            get { if (lastUpdate == null)lastUpdate = new DateTime(); return lastUpdate; }
            set
            {
                lastUpdate = value;
                Data[Constants.CONST_TAG_LASTUPDATE] = value.ToString();
            }
        }

        public string Title
        {
            get
            {
                if (Data.ContainsKey(Constants.CONST_TAG_TITLE)) return Data[Constants.CONST_TAG_TITLE];
                else return "";
            }
            set
            {
                Data[Constants.CONST_TAG_TITLE] = value;
            }
        }

        public string Description
        {
            get
            {
                if (Data.ContainsKey(Constants.CONST_TAG_DESCRIPTION)) return Data[Constants.CONST_TAG_DESCRIPTION];
                else return "";
            }
            set
            {
                Data[Constants.CONST_TAG_DESCRIPTION] = value;
            }
        }

        public string Link
        {
            get
            {
                if (Data.ContainsKey(Constants.CONST_TAG_LINK)) return Data[Constants.CONST_TAG_LINK];
                else return "";
            }
            set
            {
                Data[Constants.CONST_TAG_LINK] = value;
            }
        }

        private int schemaId;

        public int SchemaId
        {
            get { return schemaId; }
            set 
            {
                schemaId = value;
                Data[Constants.CONST_TAG_SCHEMAID] = value.ToString();
            }
        }

        private RssModel originalRss;

        public RssModel OriginalRss
        {
            get { if (originalRss == null)originalRss = new RssModel(); return originalRss; }
            set
            {
                originalRss = value;
            }
        }

        public string XmlNodeName
        {
            get
            {
                return Constants.CONST_TAG_ITEM;
            }
        }


        //public StringCollection GetFilteredResult(XmlModelCollection siteSchemas)
        //{
        //    return GetFilteredResult((SiteSchema)siteSchemas[SchemaId.ToString()]);
        //}

        //public StringCollection GetFilteredResult(SiteSchema siteSchema)
        //{
        //    StringCollection output = new StringCollection();
        //    string tmp;
        //    foreach (RssModel.RssItem i in OriginalRss.Channel.Items)
        //    {
        //        tmp = siteSchema.Filter.Match(i.Data[siteSchema.Target]);
        //        if (tmp != null && tmp != "") output.Add(tmp);
        //    }
        //    return output;
        //}

        public void Update()
        {
            originalRss = new RssModel();
            originalRss.Load(Link);
            lastUpdate = System.DateTime.Now;
        }

        public override string ToString()
        {
            return Title;
        }

        protected override void PreParseXml(XmlNode node)
        {
            //id = Convert.ToInt32(SelectNode(node, Constants.CONST_TAG_ID, true).InnerText);
            Title = SelectNode(node, Constants.CONST_TAG_TITLE, true).InnerText;
            //description = SelectNode(node, Constants.CONST_TAG_DESCRIPTION, true).InnerText;
            Link = SelectNode(node, Constants.CONST_TAG_LINK, true).InnerText;
            SchemaId = Convert.ToInt32(SelectNode(node, Constants.CONST_TAG_SCHEMAID, true).InnerText);
            LastUpdate = Convert.ToDateTime(SelectNode(node, Constants.CONST_TAG_LASTUPDATE, true).InnerText);
            XmlNode originalRssNode = SelectNode(node, Constants.CONST_TAG_ORGINALRSS, true);
            if (originalRssNode.HasChildNodes)
            {
                originalRss = new RssModel(originalRssNode);
            }
        }

        protected override void PostGenerateXml(XmlDocument doc, XmlNode newNode)
        {
            //AppendTextChildNode(doc, newNode, Constants.CONST_TAG_TITLE, Title);
            //AppendTextChildNode(doc, newNode, Constants.CONST_TAG_DESCRIPTION, Description);
            //AppendTextChildNode(doc, newNode, Constants.CONST_TAG_LINK, Link);
            //AppendTextChildNode(doc, newNode, Constants.CONST_TAG_LASTUPDATE, LastUpdate.ToString());
            //AppendTextChildNode(doc, newNode, Constants.CONST_TAG_SCHEMAID, SchemaId.ToString());
            XmlNode newOriginalRss = doc.CreateElement(Constants.CONST_TAG_ORGINALRSS);
            newOriginalRss.AppendChild(OriginalRss.ToXmlNode(doc));
            newNode.AppendChild(newOriginalRss);
        }

        #region IKeyedItem Members

        public string Key
        {
            get { return Link; }
        }

        #endregion
    }

    public class RssFeedSourceProvider : XmlModelProvider_CommonFunctions, IXmlModelProvider
    {


        #region 构造函数
        public RssFeedSourceProvider() : base() { }
        public RssFeedSourceProvider(string xml) : base(xml) { }
        public RssFeedSourceProvider(XmlNode node) : base(node) { }
        #endregion

        public override string XmlChildNodeName
        {
            get
            {
                return Constants.CONST_TAG_ITEM;
            }
        }

        public string XmlNodeName
        {
            get
            {
                return Constants.CONST_TAG_RSSFEEDLIST;
            }
        }

        public IXmlModelItem GenerateChild(XmlNode node)
        {
            return new RssFeedSource(node);
        }

        /// <summary>
        /// 更新Rss源
        /// </summary>
        public void Update()
        {
            StringWriter swExceptionDescription = new StringWriter();
            bool exceptionFlag = false;
            foreach (RssFeedSource rssNode in Items)
            {
                try
                {
                    rssNode.Update();
                }
                catch (Exception e)
                {
                    swExceptionDescription.WriteLine(rssNode.Title + " (" + e.Message + ")");
                    exceptionFlag = true;
                }
            }
            if (exceptionFlag) throw new TracyException(TracyException.EXCEPTION_FAILED_TO_REFRESH_RSS, swExceptionDescription.ToString());
        }

        public IXmlModelCollection RssItems
        {
            get
            {
                IXmlModelCollection rtn = new XmlModelCollection();
                foreach (RssFeedSource source in Items)
                {
                    foreach (RssModel.RssItem item in source.OriginalRss.Channel.Items)
                    {
                        if (!rtn.Contains(item)) rtn.Add(item);
                    }
                }
                return rtn;
            }
        }

    }
}
